import React from 'react';
import { Popover, Input, message } from 'antd';
import PropTypes from 'prop-types';
import { get, join } from 'lodash';

import copyToClipboard from '@util/copy-to-clipboard';
import { LEVEL_TEXT, LEVEL_COLOR } from '@util/constants';
import copyImg from '@images/copy.svg';
import './index.less';

const { TextArea } = Input;

// 漏洞信息页面
const OnedayDetail = props => {
  const { data = {}, showName = false } = props;
  const copyEvidence = value => {
    const res = copyToClipboard(value);
    res ? message.success('复制成功') : message.error('复制失败');
  };

  const detailItems = [
    [
      { name: '漏洞分类', path: 'vul_category' },
      { name: '影响组件', path: 'affected' },
      { name: '披露时间', path: 'lanched' }
    ],
    [
      { name: 'CVE ID', path: 'cve_id' },
      { name: 'CNNVD ID', path: 'cnnvd_id' },
      { name: 'CNVD ID', path: 'cnvd_id' }
    ],
    [
      { name: 'CWE', path: 'cwe' },
      {
        name: 'OWASP',
        path: 'owasp',
        render: owasps => (owasps.length ? join(owasps, ',') : '-')
      },
      { name: 'CVSS 3.0', path: 'cvss_3' }
    ]
  ];
  const { name, level } = data;

  const items = [
    {
      name: showName ? (
        '漏洞详情'
      ) : (
        <div>
          <span>{name || '-'}</span>
          &nbsp;&nbsp;
          <span
            className="level-wrapper"
            style={{
              color: LEVEL_COLOR[level],
              borderColor: LEVEL_COLOR[level]
            }}
          >
            {LEVEL_TEXT[level]}
          </span>
        </div>
      ),
      path: 'onedayDetailOid',
      render: (detail = {}) => (
        <div className="detail">
          {detailItems.map((items, isIndex) => {
            return (
              <div className="detail-items-wrapper" key={isIndex}>
                {items.map(({ name, path, render = i => i }, iIndex) => {
                  const message = get(detail, path, '-');
                  return (
                    <div className="detail-item" key={iIndex}>
                      <label className="detail-item__name">{name}</label>
                      {message.length > 25 ? (
                        <Popover content={message}>
                          <span className="detail-item__value">{render(message) || '-'}</span>
                        </Popover>
                      ) : (
                        <span className="detail-item__value">{render(message) || '-'}</span>
                      )}
                    </div>
                  );
                })}
              </div>
            );
          })}
        </div>
      )
    },
    {
      name: '漏洞描述',
      path: 'onedayDetailOid.description'
    },
    {
      name: '影响范围',
      path: 'onedayDetailOid.affected_version',
      render: versions => versions
    },
    {
      name: '漏洞危害',
      path: 'onedayDetailOid.harm'
    },
    {
      name: '修复建议',
      path: 'onedayDetailOid.suggestion'
    },
    {
      name: '相关链接',
      path: 'onedayDetailOid.related',
      render: (related = []) =>
        related.map(url => (
          <a className="related" href={url} target="_blank" key={url} rel="noopener noreferrer">
            {url}
          </a>
        ))
    },
    {
      name: '检测结果',
      path: '',
      render: rows => {
        let key = 'verifyInfo';
        if (get(rows, 'ps3.verifyInfo')) {
          key = 'ps3.verifyInfo';
        } else if (get(rows, 'nuclei.verifyInfo')) {
          key = 'nuclei.verifyInfo';
        } else if (get(rows, 'nscan.verifyInfo')) {
          key = 'nscan.verifyInfo';
        }
        const { Weakpass } = get(rows, key, []);
        return (
          <div>
            {Array.isArray(Weakpass) && Weakpass.length
              ? Weakpass.map(({ login, password }) => (
                  <p key={login}>
                    <span>user: {login || ''}</span>
                    <span style={{ display: 'inline-block', marginLeft: 30 }}>
                      password: {password || ''}
                    </span>
                  </p>
                ))
              : '-'}
          </div>
        );
      }
    }
  ];
  const dist = [
    'req',
    'resp',
    'nscan.detail.traffics[0]',
    'ps3.req',
    'ps3.resp',
    'verifyInfo.req',
    'nuclei'
  ];
  const reqDist = [
    'req',
    'nscan.detail.traffics[0].request',
    'ps3.req',
    'verifyInfo.req',
    'nuclei.request'
  ];
  const respDist = ['resp', 'nscan.detail.traffics[0].response', 'ps3.resp', 'nuclei.response'];

  if (
    dist.find(r => {
      return JSON.stringify(get(data, r, {})) !== '{}';
    })
  ) {
    items.splice(1, 0, {
      name: '验证方式',
      path: '',
      render: (evidence = {}) => {
        const req = JSON.stringify(
          get(
            evidence,
            reqDist.find(r => {
              return JSON.stringify(get(evidence, r, {})) !== '{}';
            })
          )
        );
        const resp = JSON.stringify(
          get(
            evidence,
            respDist.find(r => {
              return JSON.stringify(get(evidence, r, {})) !== '{}';
            })
          )
        );
        return (
          <div className="evidence">
            {resp && (
              <div className="evidence-item">
                <div className="evidence-title">
                  <span>响应体:</span>
                  <span onClick={() => copyEvidence(resp)} className="evidence-copy">
                    <img src={copyImg} />
                    复制
                  </span>
                </div>
                <TextArea value={resp} autosize={{ minRows: 3, maxRows: 5 }} />
              </div>
            )}
            {req && (
              <div className="evidence-item">
                <div className="evidence-title">
                  <span>请求:</span>
                  <span onClick={() => copyEvidence(req)} className="evidence-copy">
                    <img src={copyImg} />
                    复制
                  </span>
                </div>
                <TextArea value={req} autosize={{ minRows: 3, maxRows: 5 }} />
              </div>
            )}
          </div>
        );
      }
    });
  }

  return (
    <div className="tmo-c-oneday-detail">
      {items.map((item, index) => {
        const { name, path, render } = item;
        const value = path ? get(data, path) : data;
        const exactValue = typeof render === 'function' ? render(value, item) : value;
        return (
          <div className="item" key={index}>
            <div className="item__name">{name}</div>
            <div className="item__value">{exactValue || '-'}</div>
          </div>
        );
      })}
    </div>
  );
};

OnedayDetail.propTypes = {
  data: PropTypes.object,
  showName: PropTypes.bool
};

export default OnedayDetail;
